#include <iostream>
#include <cstring>
#define MAXN 20
using namespace std;
int M, N;
int origin[MAXN][MAXN], temp[MAXN][MAXN], opt[MAXN][MAXN];
int dxdy[][5] = {
    {0, 1, -1, 0, 0},
    {0, 0, 0, 1, -1}
};
void solve();
int main() {
    cin >> M >> N;
    for (int i = 0; i < M; i++) 
        for (int j = 0; j < N; j++) 
            cin >> origin[i][j];

    solve();
}

// 计算当前位置的颜色
int get(int x, int y) {
    int c = origin[x][y];
    for (int i = 0; i < 5; i++) {
        int nx = x + dxdy[0][i], ny = y + dxdy[1][i];
        if (nx >= 0 && nx < M && ny >= 0 && ny < N) c += temp[nx][ny];
    }
    return c % 2;
}

// 求出第一行确定的最小操作数
int calc() {
    for (int i = 1; i < M; i++) {
        for (int j = 0; j < N; j++) {
            if (get(i - 1, j) != 0) temp[i][j] = 1;
        }
    }

    for (int j = 0; j < N; j++) {
        if (get(M - 1, j) != 0) return -1;
    }

    int res = 0;
    for (int i = 0; i < M; i++)
        for (int j = 0; j < N; j++)
            res += temp[i][j];
    return res;
}

void solve() {
    int res = -1;
    for (int i = 0; i < 1 << N; i++) {
        memset(temp, 0, sizeof temp);
        for (int j = 0; j < N; j++) 
            temp[0][N - j -1] = i >> j & 1;
        int num = calc();
        if (num >= 0 && (res < 0 || res > num)) {
            res = num;
            memcpy(opt, temp, sizeof opt);
        }
    }
    if (res < 0) {
        cout << "IMPOSSIBLE\n" << endl;
    } else {
        for (int i = 0; i < M; i++) {
            for (int j = 0; j < N; j++) {
                printf("%d%c", opt[i][j], j + 1 == N ? '\n': ' ');
            }
        }
    }
}